package com.acmen.easyapi.generator;

import com.acmen.easyapi.annotation.EnumValue;
import com.acmen.easyapi.annotation.Param;
import com.acmen.easyapi.util.EnumUtil;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Random;

/**
 * @author acmen
 * 枚举数据获取器
 */
@Component
public class EnumDataGenerator implements DataGenerator {
    private Random random = new Random();

    /**
     * 判断字段类型是否为枚举或参数中的枚举类是否为枚举
     *
     * @param field 字段
     * @param param 参数
     * @return 如果字段类型为枚举或参数中的枚举类为枚举，返回true；否则返回false
     */
    @Override
    public boolean matches(Field field, Param param) {
        return field.getType().isEnum() || param.enumClass().isEnum();
    }

    /**
     * 生成枚举数据
     *
     * @param field 字段
     * @param param 参数
     * @return 随机生成的枚举数据
     */
    @Override
    public Object generate(Field field, Param param) {
         // 判断字段类型是否为枚举
        if (field.getType().isEnum()) {
            // 获取枚举类型的所有常量数量
            int len = field.getType().getEnumConstants().length;
            // 生成一个随机的下标
            int idx = random.nextInt(len);
            // 返回对应下标的枚举常量
            return field.getType().getEnumConstants()[idx];
        } else {
            // 获取参数中枚举类型的枚举常量数量
            int len = param.enumClass().getEnumConstants().length;
            // 生成一个随机的下标
            int idx = random.nextInt(len);
            // 获取对应下标的枚举常量对象
            Object enumObject = param.enumClass().getEnumConstants()[idx];
            // 查找参数中枚举类型上的注解EnumValue
            EnumValue enumValue = AnnotatedElementUtils.findMergedAnnotation(param.enumClass(), EnumValue.class);
            if (enumValue != null) {
                // 如果字段是数组或可变集合类型
                if (field.getType().isArray() || Collection.class.isAssignableFrom(field.getType())) {
                    // 返回包含枚举常量的数组
                    return new Object[]{enumObject};
                } else {
                    // 返回枚举常量对象
                    return enumObject;
                }
            } else {
                // 获取枚举常量对应的值
                Object data = EnumUtil.getEnumValue(enumObject);
                if (field.getType().isArray() || Collection.class.isAssignableFrom(field.getType())) {
                    // 如果值不为空，返回包含值的数组，否则返回空数组
                    if (data != null) {
                        return new Object[]{data};
                    } else {
                        return new Object[]{};
                    }
                } else {
                    // 如果值不为空，返回值，否则返回空字符串
                    if (data != null) {
                        return data;
                    } else {
                        return "";
                    }
                }
            }
        }
    }

    /**
     * 数据获取说明
     *
     * @return 枚举类：当字段类型为枚举时，随机获取枚举类里的一个值。
     */
    @Override
    public String getNote() {
        return "枚举类：当字段类型为枚举时，随机获取枚举类里的一个值。";
    }
}
